package jwt

import (
	"github.com/golang-jwt/jwt/v5"
	"strings"
	"time"
)

type (
	// ClaimsItem JWT配置要求属性
	ClaimsItem struct {
		Issuer           string // JWT的签发者。例如，如果一个网站发行了一个JWT，那么签发者可能就是这个网站的URL
		Subject          string // JWT的主题。主题通常是发行者的标识符，或者是表示JWT所代表的对象或用户的标识符。
		ExpireUnit       string // 效期单位,h小时，d天
		ExpireAt         uint   // 过期时间
		SigningAlgorithm string // 加密方式：
		Secret           string // 加密密钥
		TokenLookup      string // Token检索模式, Header
		TokenHeadName    string // token在请求头时的名称，默认值为Bearer
		MaxRefreshCount  uint   // Token最大刷新次数
	}

	// JWTClaimsItem 注册JWT属性
	JWTClaimsItem struct {
		Claims     jwt.RegisteredClaims // 注册签名要求
		SignMethod jwt.SigningMethod    // 签名加密方式
		ClaimsItem
	}

	// AccountDetail 账户信息
	AccountDetail struct {
		Uid          uint   // 用户ID
		Account      string // 账户
		Nickname     string // 昵称
		RefreshCount uint   // 刷新次数
	}

	// TokenItem 签名后token信息
	TokenItem struct {
		Token  string `json:"token" dc:"Token值"`
		Expire string `json:"expire" dc:"过期时间"`
	}

	// AuthTokenItem 刷新授权Token信息
	AuthTokenItem struct {
		Used         bool // Token是否已使用
		RefreshCount uint // 刷新次数
		TokenItem         // token信息
	}

	// RegisteredClaimsItem JWT账户发行属性
	RegisteredClaimsItem struct {
		AccountDetail
		jwt.RegisteredClaims
	}
)

// registerClaimsItem 注册JWT要求属性
func registerClaimsItem(claims ClaimsItem) *JWTClaimsItem {
	item := jwt.RegisteredClaims{
		Issuer:    claims.Issuer,
		Subject:   claims.Subject,
		IssuedAt:  jwt.NewNumericDate(time.Now()),
		NotBefore: jwt.NewNumericDate(time.Now()),
	}
	var timeout time.Duration
	// 设置过期时间
	switch strings.ToLower(claims.ExpireUnit) {
	case `d`:
		// 按天
		timeout = time.Hour * 24 * time.Duration(claims.ExpireAt)
	default:
		// 按时间
		timeout = time.Minute * time.Duration(claims.ExpireAt)
	}
	item.ExpiresAt = jwt.NewNumericDate(time.Now().Add(timeout))

	// 返回JWT注册要求
	return &JWTClaimsItem{
		Claims:     item,
		SignMethod: jwt.GetSigningMethod(claims.SigningAlgorithm),
		ClaimsItem: claims,
	}
}
